﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Windows.Forms;
using System.Threading;
using System.ComponentModel;
using System.Reflection;
using System.IO;
using System.ServiceProcess;
using System.Net;
using System.Data;
using System.Text.RegularExpressions;
using System.Net.Mail;

namespace CSI300Cons.CapitalDownloader
{
    public class Program : ServiceBase
    {
        #region Framework Configuration
        
        private static System.Timers.Timer timerConsole = new System.Timers.Timer();
        private static System.Timers.Timer timerSingleThreadTask = new System.Timers.Timer();

        private static int ClearConsoleInterval = Convert.ToInt32(ConfigurationManager.AppSettings["ClearConsoleInterval"]) * 1000;
        private static int MainTaskInterval = Convert.ToInt32(ConfigurationManager.AppSettings["MainTaskInterval"]) * 1000;
        private static int BreathInterval = Convert.ToInt32(ConfigurationManager.AppSettings["BreathInterval"]);
        private static int RunOnce = Convert.ToInt32(ConfigurationManager.AppSettings["RunOnce"]);

        private static int Debug = 0;

        private static string ServiceRealName = ConfigurationManager.AppSettings["ServiceName"];
        private static string ServiceDisPlayName = ConfigurationManager.AppSettings["ServiceDisPlayName"];
        private static string ServiceDescription = ConfigurationManager.AppSettings["ServiceDescription"];
        private static bool LogToFile = (ConfigurationManager.AppSettings["LogToFile"] == "1");

        private static object obj = new object();

        private static string ServicePath = Application.ExecutablePath;
        private static string ServiceDirectory = Path.GetDirectoryName(ServicePath);

        //定义发送线程
        private static int MutiThreadCount = Convert.ToInt32(ConfigurationManager.AppSettings["MutiThreadCount"]);
        private static Thread[] WorkThreads;
        private static bool Stopped = false;
        private static Dictionary<string, bool> ThreadStatus = new Dictionary<string, bool>();

        private static ITask singletask;

        #endregion

        public static Log Logger;

        #region 应用程序入口

        static void Main(string[] args)
        {
            Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

            bool exists = ServiceControl.CheckService(ServiceRealName);

            if (args.Length == 0)
            {
                ServiceBase.Run(new ServiceBase[] { new Program() });
            }
            else
            {
                string parm = args[0].ToLower();

                switch (parm)
                {

                    case "-debug":
                    case "/debug":

                        Debug = 1;

                        if (exists)
                        {
                            ServiceControllerStatus status = ServiceControl.GetServiceStatus(ServiceRealName);

                            if (status != ServiceControllerStatus.Stopped)
                            {
                                Console.WriteLine(Log.GetDateTime() + ServiceRealName + " 服务正在运行，无法进入调试状态。请先停止该服务");
                                Console.ReadLine();
                            }
                            else
                            {
                                InitilizeCompoment();
                            }
                        }
                        else
                        {
                            InitilizeCompoment();
                        }


                        break;

                    case "-install":
                    case "-setup":
                    case "/install":
                    case "/setup":

                        if (exists)
                        {
                            Console.WriteLine(Log.GetDateTime() + ServiceRealName + " 服务已经存在，如果您想升级服务，请先卸载该服务");
                            Console.ReadLine();
                        }
                        else
                        {
                            Console.WriteLine(Log.GetDateTime() + ServicePath);

                            bool result = ServiceControl.InstallService(ServicePath, ServiceRealName, ServiceDisPlayName, ServiceDescription);

                            if (result)
                            {
                                Console.WriteLine(Log.GetDateTime() + "服务安装成功");
                                Console.WriteLine(Log.GetDateTime() + "正在启动服务...");

                                ServiceControl.StartService(ServiceRealName);

                                while (!(ServiceControl.GetServiceStatus(ServiceRealName) == ServiceControllerStatus.Running))
                                {
                                    while (!(ServiceControl.GetServiceStatus(ServiceRealName) == ServiceControllerStatus.Running))
                                    {
                                        Thread.Sleep(BreathInterval);
                                    }
                                }

                                Console.WriteLine(Log.GetDateTime() + "服务已经启动");
                            }
                            else
                            {
                                Console.WriteLine(Log.GetDateTime() + "服务安装失败");
                            }

                            Console.ReadLine();
                        }
                        break;

                    case "-uninstall":
                    case "-remove":
                    case "/uninstall":
                    case "/remove":

                        if (!exists)
                        {
                            Console.WriteLine(Log.GetDateTime() + ServiceRealName + " 服务尚未安装");
                        }
                        else
                        {
                            bool result = ServiceControl.UnInstallService(ServiceRealName);

                            if (!result)
                            {
                                Console.WriteLine(Log.GetDateTime() + "服务卸载失败");
                            }
                            else
                            {
                                Console.WriteLine(Log.GetDateTime() + "服务卸载成功");
                            }                          
                        }
                        Console.ReadLine();
                        break;
                    case "-stop":
                    case "/stop":

                        if (!exists)
                        {
                            Console.WriteLine(Log.GetDateTime() + ServiceRealName + " 服务尚未安装");
                        }
                        else
                        {
                            try
                            {
                                ServiceControl.StopService(ServiceRealName);
                                Console.WriteLine(Log.GetDateTime() + "服务停止成功");
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(Log.GetDateTime() + "服务停止失败：" + ex.Message); 
                            }
                        }

                        Console.ReadLine();
                        break;
                    case "-start":
                    case "/start":

                        if (!exists)
                        {
                            Console.WriteLine(Log.GetDateTime() + ServiceRealName + " 服务尚未安装");
                        }
                        else
                        {
                            try
                            {
                                ServiceControl.StartService(ServiceRealName);
                                Console.WriteLine(Log.GetDateTime() + "服务启动成功");
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(Log.GetDateTime() + "服务启动失败：" + ex.Message);
                            }
                        }

                        Console.ReadLine();
                        break;
                }
            }
        }

        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            Logger.Output("未处理A：" + e.Exception.Message, ConsoleColor.Red, true);
        }

        static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is System.Exception)
            {
                Logger.Output("未处理P：" + ((System.Exception)e.ExceptionObject).Message, ConsoleColor.Red, true);
            }

        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {

            }

            base.Dispose(disposing);
        }

        public Program()
        {
            base.ServiceName = ServiceRealName;
            base.AutoLog = true;
        }

        #endregion

        #region 初始化应用程序

        /// <summary>
        /// 初始化应用程序
        /// </summary>
        private static void InitilizeCompoment()
        {
            Logger = new Log(Debug, ServiceDirectory);

            if (Debug == 1)
            {
                Console.Title = ServiceDisPlayName;
            }

            Logger.Output("程序初始化", true);

            InitilizeTimer();
            Logger.Output("初始化定时器", true);

            singletask = new DownloaderTask();

            if (Debug == 1)
            {
                SingleThreadTask();
            }

            Logger.Output("单线程工作初始化", true);

            if (MutiThreadCount>0)
            {
                WorkThreads = new Thread[MutiThreadCount];
                ThreadStatus.Clear();
                for (int i = 0; i < MutiThreadCount; i++)
                {
                    WorkThreads[i] = new Thread(new ParameterizedThreadStart(MutiThreadTask));
                    WorkThreads[i].Name = i.ToString();
                    WorkThreads[i].IsBackground = false;
                    WorkThreads[i].Start(i);
                }
                Logger.Output("多线程工作初始化", true);
            }

            if (Debug == 1)
            {
                if (RunOnce == 0)
                {
                    Console.ReadLine();
                }
            }
        }

        #endregion

        #region 业务逻辑

        private static void SingleThreadTask()
        {
            singletask.MainTaskExecute();
        }

        private static void MutiThreadTask(object param)
        {
            //int i = (int)param;
            //ITask task = new DownloaderTask();

            //while (true)
            //{
            //    //如果处于停止服务请求下
            //    if (Stopped)
            //    {
            //        lock (obj)
            //        {
            //            ThreadStatus[i.ToString()] = true;
            //        }
            //        //跳出循环
            //        break;

            //        task.MainTaskExecute();
            //    }

            //    Thread.Sleep(MainTaskInterval);
            //}
        }

        #endregion

        #region 初始化服务设置

        protected override void OnStart(string[] args)
        {
            InitilizeCompoment();
        }

        protected override void OnStop()
        {
            //停止定时器
            timerConsole.Enabled = false;
            timerSingleThreadTask.Enabled = false;

            //通知线程结束循环
            Stopped = true;

            while (!AllStop())
            {
                Thread.Sleep(MainTaskInterval);
            }
        }

        /// <summary>
        /// 判断工作线程是否已经都停止了
        /// </summary>
        /// <returns></returns>
        private static bool AllStop()
        {
            try
            {
                lock (obj)
                {
                    foreach (bool value in ThreadStatus.Values)
                    {
                        if (!value)
                        {
                            return false;
                        }
                    }
                }

                return true;
            }
            catch (Exception e)
            {
                Logger.Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);

                return false;
            }
        }

        #endregion

        #region 初始化定时器
        /// <summary>
        /// 初始化定时器
        /// </summary>
        private static void InitilizeTimer()
        {
            // 定时清理控制台
            timerConsole.Interval = ClearConsoleInterval;
            timerConsole.Enabled = true;
            timerConsole.Elapsed += new System.Timers.ElapsedEventHandler(timerConsole_Elapsed);
            timerConsole.AutoReset = true;

            timerSingleThreadTask.Interval = MainTaskInterval;
            timerSingleThreadTask.Enabled = true;
            timerSingleThreadTask.Elapsed += new System.Timers.ElapsedEventHandler(timerSingleThreadTask_Elapsed);
            timerSingleThreadTask.AutoReset = true;
        }

        static void timerSingleThreadTask_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            SingleThreadTask();
        }

        /// <summary>
        /// debug模式下定时清空控制台
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void timerConsole_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (Debug == 1)
            {
                Console.Clear();
                Logger.Output("控制台已更新");
            }
        }

        #endregion

        #region 调试辅助逻辑

        #endregion
    }
}
